home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
301-325
/
disk_302
/
turbomandel
/
source
/
turbomandel.c
< prev
Wrap
C/C++ Source or Header
|
1992-05-06
|
39KB
|
1,196 lines
/*******************************
* TURBOMANDEL 1.0 *
* by Philip Marivoet *
* Nico Francois *
*******************************/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <hardware/custom.h>
#include <graphics/copper.h>
#include <graphics/gfxmacros.h>
#include <stdio.h>
#include <math.h>
#include <libraries/arpbase.h>
#include <proto/arp.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
extern struct Custom __far custom;
#define ISCHECKED(x) (x.Flags & CHECKED)
#define CHECK(x) (x.Flags |=CHECKED)
#define UNCHECK(x) (x.Flags &=~CHECKED)
#define TITLECHECK ShowTitle(ManScr,(ISCHECKED(TitleItem) ? TRUE : FALSE))
/* assembler function call structure */
extern LONG __asm Int32Mand_asm(register __a0 LONG,register __a1 LONG,register __d0 LONG);
extern LONG __asm FloatMand_asm(register __a0 float,register __a1 float,register __d0 LONG);
extern void __asm DoCycle_asm();
extern void __asm PaletteLeft();
extern void __asm PaletteRight();
extern void __asm F2I(register __a0 ULONG *,register __d0 float);
extern float __asm I2F(register __a0 ULONG *);
/**********
* Palette *
**********/
#define OK 10
#define CANCEL 11
#define RED 12
#define GREEN 13
#define BLUE 14
#define INTPLUS 15
#define INTMIN 16
#define SLOPEPLUS 17
#define SLOPEMIN 18
#define TOPRIGHT 19
#define TOPLEFT 20
SHORT BorderVectors1[] = { 0,0,26,0,26,11,0,11,0,0 };
SHORT BorderVectors2[] = { 0,0,52,0,52,12,0,12,0,0 };
struct Border Border26x11 = { -2,-1,3,0,JAM1,5,BorderVectors1,NULL };
struct Border Border52x12 = { -2,-1,3,0,JAM1,5,BorderVectors2,NULL };
#define MakeGText(n,x,y,t) struct IntuiText n =\
{ 1,0,JAM1,x,y,NULL,(UBYTE *)t,NULL }
MakeGText (DecrText,8,1,"-");
MakeGText (IncrText,8,1,"+");
MakeGText (RightText,8,1,">");
MakeGText (LeftText,8,1,"<");
MakeGText (GreenText,8,1,"G");
MakeGText (RedText,8,1,"R");
MakeGText (BlueText,8,1,"B");
MakeGText (CancelText,1,2,"CANCEL");
MakeGText (OkText,17,2,"OK");
#define MakeRText(n,x,y,t) struct IntuiText n =\
{ 2,0,JAM1,x,y,NULL,(UBYTE *)t,NULL}
MakeRText (BodyText,5,5,"");
MakeRText (YesText,5,3,"");
MakeRText (NoText,5,3,"");
struct IntuiText PText = { 1,0,JAM1,35,58,NULL,(UBYTE *)"P",NULL };
struct IntuiText SText = { 1,0,JAM1,75,63,NULL,(UBYTE *)"S",&PText };
struct IntuiText IText = { 1,0,JAM1,151,63,NULL,(UBYTE *)"I",&SText };
#define MakeGBox(n,p,x,y,t,id) struct Gadget n = {p,x,y,23,10,NULL\
,RELVERIFY,BOOLGADGET,(APTR)&Border26x11,NULL,&t,NULL,NULL,id,NULL}
MakeGBox (DecrIntG,NULL,123,69,DecrText,INTMIN);
MakeGBox (IncrIntG,&DecrIntG,123,54,IncrText,INTPLUS);
MakeGBox (DecrSlopeG,&IncrIntG,88,69,DecrText,SLOPEMIN);
MakeGBox (IncrSlopeG,&DecrSlopeG,88,54,IncrText,SLOPEPLUS);
MakeGBox (RightTopG,&IncrSlopeG,43,69,RightText,TOPRIGHT);
MakeGBox (LeftTopG,&RightTopG,11,69,LeftText,TOPLEFT);
MakeGBox (GreenG,&LeftTopG,219,54,GreenText,GREEN);
MakeGBox (BlueG,&GreenG,261,54,BlueText,BLUE);
MakeGBox (RedG,&BlueG,178,54,RedText,RED);
struct Gadget CancelGb = { &RedG,235,69,49,11,NULL,RELVERIFY,BOOLGADGET,
(APTR)&Border52x12,NULL,&CancelText,NULL,NULL,CANCEL,NULL };
struct Gadget OkGb = { &CancelGb,178,69,49,11,NULL,RELVERIFY,BOOLGADGET,
(APTR)&Border52x12,NULL,&OkText,NULL,NULL,OK,NULL };
struct NewWindow NewPalWin = { 14,88,292,85,0,1,RAWKEY+GADGETDOWN+GADGETUP,
WINDOWDRAG+ACTIVATE+RMBTRAP+NOCAREREFRESH,&OkGb,NULL,(UBYTE *)"Palette",
NULL,NULL,5,5,640,200,CUSTOMSCREEN };
/*********
* Coords *
*********/
SHORT Vectors1[] = { 0,0,187,0,187,9,0,9,0,0 };
struct Border Border187x9 = { -1,-1,1,0,JAM1,5,Vectors1,NULL};
/* GADGETS */
struct Gadget CancelG = { NULL,125,86,49,11,NULL,RELVERIFY,BOOLGADGET,
(APTR)&Border52x12,NULL,&CancelText,NULL,NULL,CANCEL,NULL };
struct Gadget OkG = { &CancelG,23,86,49,11,NULL,RELVERIFY,BOOLGADGET,
(APTR)&Border52x12,NULL,&OkText,NULL,NULL,OK,NULL };
UBYTE bottomrighty[22], bottomrightx[22], toplefty[22], topleftx[22];
struct StringInfo BRyGInfo = { bottomrighty,NULL,0,22,0,0,0,0,0,0,0,0,NULL };
struct StringInfo BRxGInfo = { bottomrightx,NULL,0,22,0,0,0,0,0,0,0,0,NULL };
struct StringInfo TLyGInfo = { toplefty,NULL,0,22,0,0,0,0,0,0,0,0,NULL };
struct StringInfo TLxGInfo = { topleftx,NULL,0,22,0,0,0,0,0,0,0,0,NULL };
#define MakeCoordBox(n,p,x,y,info) struct Gadget n = {p,x,y,184,8,NULL,\
RELVERIFY+STRINGCENTER,STRGADGET,(APTR)&Border187x9,NULL,NULL,NULL,\
(APTR)&info,NULL,NULL }
MakeCoordBox(BRyG,&OkG, 8,72,BRyGInfo);
MakeCoordBox(BRxG,&BRyG,8,60,BRxGInfo);
MakeCoordBox(TLyG,&BRxG,8,36,TLyGInfo);
MakeCoordBox(TLxG,&TLyG,8,24,TLxGInfo);
struct IntuiText BRText =
{ 1,0,JAM1,10,49,NULL,(UBYTE *)"Bottom right:",NULL };
struct IntuiText TLText =
{ 1,0,JAM1,10,13,NULL,(UBYTE *)"Top left:",&BRText };
struct NewWindow newcoowin = { 60,79,200,100,0,1,GADGETDOWN+GADGETUP,
WINDOWDRAG+ACTIVATE+RMBTRAP+NOCAREREFRESH,&TLxG,NULL,
(UBYTE *)"Enter Coordinates",NULL,NULL,5,5,640,200,CUSTOMSCREEN };
/***************
* filenamereq *
***************/
#define STRING 180
SHORT BorderVectors3[] = { 0,0,165,0,165,12,0,12,0,1 };
struct Border Border12x165 = { -3,-2,3,0,COMPLEMENT,5,BorderVectors3,NULL };
struct StringInfo StringGInfo = { NULL,NULL,0,64,0,0,0,0,0,0,0,0,NULL };
struct Gadget StringG = { NULL,20,20,160,9,NULL,RELVERIFY+STRINGCENTER,
STRGADGET,(APTR)&Border12x165,NULL,NULL,NULL,(APTR)&StringGInfo,STRING,NULL };
struct NewWindow NewStringWin = { 0,0,200,40,0,1,GADGETUP,
WINDOWDRAG+ACTIVATE+NOCAREREFRESH,&StringG,NULL,
(UBYTE *)"Enter Filename",NULL,NULL,5,5,640,200,CUSTOMSCREEN };
/********
* Menus *
********/
#define makeMenuText(x,s,off) struct IntuiText x = {\
3,1,COMPLEMENT,0,off,NULL,(UBYTE *)s,NULL }
#define makeMenuTextCheck(x,s,o) struct IntuiText x = {\
3,1,COMPLEMENT,19,o,NULL,(UBYTE *)s,NULL }
#define makeITEM(x,y,h,w,t) struct MenuItem x = { y,0,h,w,9,ITEMTEXT\
+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL }
#define makeITEMCheckME(x,y,h,w,t,me) struct MenuItem x = { y,0,h,w,9,CHECKIT\
+ITEMTEXT+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL }
#define makeITEMc(x,y,h,w,t,c) struct MenuItem x = { y,0,h,w,9,ITEMTEXT+\
ITEMENABLED+HIGHCOMP+COMMSEQ,0,(APTR)&t,NULL,c,NULL,MENUNULL }
#define makeITEMcCheckT(x,y,h,w,t,c) struct MenuItem x = {\
y,0,h,w,9,CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP+COMMSEQ,\
NULL,(APTR)&t,NULL,c,NULL,MENUNULL }
#define makeSUBCheckME(x,y,h,w,l,t,me) struct MenuItem x = { y,l,h,w,9,\
CHECKIT+ITEMTEXT+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL }
#define makeITEMCheckT(x,y,h,w,t) struct MenuItem x = { y,0,h,w,9,CHECKIT+\
ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL }
#define makeITEMCheckTME(x,y,h,w,t,me) struct MenuItem x = { y,0,h,w,9,CHECKIT+\
ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL}
#define makeITEMSub(x,y,h,w,t,s) struct MenuItem x = {\
y,0,h,w,9,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,&s,MENUNULL }
#define makeSUBItem(x,y,h,w,l,t) struct MenuItem x = {\
y,l,h,w,9,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL }
#define makeMENU(m,n,x,w,s,i) struct Menu m = { n,x,0,w,0,MENUENABLED,s,i }
/*************
* Screenmenu *
*************/
makeMenuTextCheck (HiresText,"Hires",1);
makeMenuTextCheck (InterText,"Interlace",1);
makeMenuTextCheck (EHBText,"EHB",1);
makeMenuTextCheck (TurboText,"Turbo",1);
makeMenuTextCheck (ThreeDText,"3-D",1);
makeMenuText (NewScrText,"New Screen",1);
makeMenuText (PaletteText,"Palette",1);
makeITEMc (PalItem,NULL,54,95,PaletteText,'P');
makeITEM (NewScrItem,&PalItem,45,95,NewScrText);
makeITEMCheckT (ThreeDItem,&NewScrItem,36,95,ThreeDText);
makeITEMCheckTME (EHBItem,&ThreeDItem,27,95,EHBText,0x0002);
makeITEMcCheckT (TurboItem,&EHBItem,18,95,TurboText,'T');
makeITEMCheckTME (HiresItem,&TurboItem,9,95,HiresText,0x0008);
makeITEMCheckT (InterItem,&HiresItem,0,95,InterText);
makeMENU (ScreenMenu,NULL,164,66,"Screen",&InterItem);
/***************
* fractalmenu *
***************/
makeMenuTextCheck (SuperText,"Super",1);
makeMenuTextCheck (BestText,"Best",1);
makeMenuTextCheck (GoodText,"Good",1);
makeMenuTextCheck (NormalText,"Normal",1);
makeMenuTextCheck (LowText,"Low",1);
makeSUBCheckME (SuperItem, NULL,24,67,73,SuperText,0x000F);
makeSUBCheckME (BestItem,&SuperItem,16,67,73,BestText,0x0017);
makeSUBCheckME (GoodItem,&BestItem,8,67,73,GoodText,0x001B);
makeSUBCheckME (NormItem,&GoodItem,0,67,73,NormalText,0x001D);
makeSUBCheckME (LowItem,&NormItem,-8,67,73,LowText,0x001E);
makeMenuTextCheck (D32Text,"32",1);
makeMenuTextCheck (D64Text,"64",1);
makeMenuTextCheck (D128Text,"128",1);
makeMenuTextCheck (D256Text,"256",1);
makeMenuTextCheck (D512Text,"512",1);
makeMenuTextCheck (D1024Text,"1024",1);
makeMenuTextCheck (DCustText,"Custom",1);
makeSUBCheckME (DCustItem,NULL,40,68,73,DCustText,0x3F);
makeSUBCheckME (D1024Item,&DCustItem,32,68,73,D1024Text,0x5F);
makeSUBCheckME (D512Item,&D1024Item,24,68,73,D512Text,0x6F);
makeSUBCheckME (D256Item,&D512Item,16,68,73,D256Text,0x77);
makeSUBCheckME (D128Item,&D256Item, 8,68,73,D128Text,0x7B);
makeSUBCheckME (D64Item,&D128Item, 0,68,73,D64Text,0x7D);
makeSUBCheckME (D32Item,&D64Item,-8,68,73,D32Text,0x7E);
makeMenuTextCheck (IntText,"Integer",1);
makeMenuTextCheck (FloatText,"Float",1);
makeSUBCheckME (FloatItem,NULL,0,75,73,FloatText,0x0001);
makeSUBCheckME (IntItem,&FloatItem,-8,75,73,IntText,0x0002);
makeMenuText (AccText,"Accuracy",1);
makeMenuText (DepthText,"Depth",1);
makeMenuText (CalcText,"Calculation",1);
makeMenuText (CoordText,"Coords",1);
makeMenuText (ResetText,"Reset",1);
makeMenuText (RestText,"Restart",1);
makeITEM (RestItem,NULL,45,88,RestText);
makeITEM (ResetItem,&RestItem,36,88,ResetText);
makeITEMc (CoordItem,&ResetItem,27,88,CoordText,'C');
makeITEMSub (CalcItem,&CoordItem,18,88,CalcText,IntItem);
makeITEMSub (DepthItem,&CalcItem,9,88,DepthText,D32Item);
makeITEMSub (AccItem,&DepthItem,0,88,AccText,LowItem);
makeMENU (MandelMenu,&ScreenMenu,82,75,"Mandel",&AccItem);
/***************
* ProjectMenu *
***************/
makeMenuText (AboutText,"About",1);
makeMenuText (LoadText,"Load",1);
makeMenuText (SaveText,"Save",1);
makeMenuTextCheck (TitleText,"Title",1);
makeMenuText (QuitText,"Quit",1);
makeITEMc (QuitItem,NULL,36,80,QuitText,'Q');
makeITEMCheckT (TitleItem,&QuitItem,27,80,TitleText);
makeITEMc (AboutItem,&TitleItem,18,80,AboutText,'A');
makeITEMc (SaveItem,&AboutItem,9,80,SaveText,'S');
makeITEMc (LoadItem,&SaveItem,0,80,LoadText,'L');
makeMENU (ProjectMenu,&MandelMenu,0,75,"Project",&LoadItem);
#define PROJECT 0
#define LOAD 0
#define SAVE 1
#define ABOUT 2
#define TITLE 3
#define QUIT 4
#define MANDEL 1
#define ACCURACY 0
#define SUPER 4
#define DEPTH 1
#define CUSTOMD 6
#define CALCULATION 2
#define INTCALC 0
#define FLOATCALC 1
#define COORD 3
#define RESET 4
#define RESTART 5
#define SCREEN 2
#define TURBO 2
#define NEWSCR 5
#define PALETTE 6
struct TextAttr TOPAZ80 = { (STRPTR)"topaz.font",TOPAZ_EIGHTY,0,0 };
struct NewScreen ScrStruct = { 0,0,320,256,5,0,1,NULL,CUSTOMSCREEN,&TOPAZ80,
(UBYTE *)"TurboMandel V1.0",NULL,NULL};
struct NewWindow WinStruct = { 0,0,320,256,0,1,RAWKEY+MENUPICK+MOUSEBUTTONS
+MOUSEMOVE,BORDERLESS+NOCAREREFRESH+ACTIVATE+BACKDROP,NULL,NULL,NULL,
NULL,NULL,640,512,640,512,CUSTOMSCREEN};
USHORT Palette[32] = { 0x3a,0xfff,0x2,0xf00 };
/* for IFF read/write */
struct BitMapHeader {
UWORD w, h, x, y;
UBYTE nPlanes, masking, compression, pad1;
UWORD transparentColor;
UBYTE xAspect, yAspect;
WORD pageWidth, pageHeight;
};
struct ILBM_info {
struct BitMapHeader header;
struct BitMap bitmap;
UBYTE cmap[32*3];
};
extern BOOL iff_read(), iff_write();
struct ILBM_info myILBMinfo;
#define CALC_FFP 0
#define CALC_INT32 1
#define MAND_3D 1
struct MandelChunk {
ULONG XCoo[2], YCoo[2], XSide[2], YSide[2];
UWORD Iteration;
UBYTE Calculation, Flags;
SHORT TopPos[3], DecrStep[3], ColInt[3]; /* for Palette */
} MandChunk;
struct FileRequester *req = NULL;
extern struct Library *MathTransBase;
extern struct Library *MathBase;
extern struct ExecBase *SysBase;
struct ArpBase *ArpBase;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *ManScr = NULL;
struct Window *ManWin = NULL,*PalWin,*CoordWin,*StringWin;
struct ViewPort *Manvp;
struct RastPort *Manrp,*Palrp,*Coordrp;
void (*Dot)(), Dot2D(), Dot3D(), (*Box)(), Box2D(), Box3D();
LONG (*Mand)(), FloatMand(), Int32Mand();
LONG (*CalcMandel)(), CalcMandel2D(), CalcMandel3D();
void AdjustArpReq (ULONG, struct NewWindow *);
UBYTE *GetName ();
double cos();
LONG MaxIter, Depth, TurboDepth, DotsH, DotsV, ColorMax;
LONG XOffset, YOffset, NumCol, XRes, YRes, Factor;
SHORT StopCalc, Stopped, Restart = TRUE, CalcAllPoints, DivDegree, DivNumber;
SHORT i, BoxOn = FALSE, CycleOn = FALSE, CycleTemp, CycleLeft = TRUE;
SHORT PaletteOn = FALSE, CycleSpeed = 4, CurrSpeed = 4, NoZoom = FALSE;
UBYTE fname[64], ItBuffer[64];
float xmin, xmax, ymin, ymax, dx, dy;
LONG ScrH;
#define PI2 1.570796327
#define R 0
#define G 1
#define B 2
SHORT toppos[3] = { 7,14,21 }, decrstep[3] = { 17,17,17 };
SHORT colint[3] = { 15,15,15 };
main()
{
if (ArpBase = (struct ArpBase *)OpenLibrary ("arp.library",0L)) {
if (req = ArpAllocFreq()) {
req->fr_Function = AdjustArpReq;
req->fr_FuncFlags = FRF_NewWindFunc;
req->fr_Window = 0;
}
}
if (!(MathTransBase=(struct Library *)OpenLibrary("mathtrans.library",0L))) {
puts ("No mathtrans.library !");
exit (20);
}
if (!(MathBase=(struct Library *)OpenLibrary("mathffp.library",0L))) {
CloseLibrary (MathTransBase);
puts ("No math.library !");
exit (20);
}
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L);
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L);
/* PAL or NTSC ? */
ScrH = (SysBase->VBlankFrequency == 60) ? 200 : 256;
PalSinus (R); PalSinus (G); PalSinus (B);
xmax = 1.25; xmin = -2.25; ymax = 1.5; ymin = -1.5;
MaxIter = 64 ; CHECK (D64Item);
DivNumber = 2 ; CHECK (NormItem);
Mand = Int32Mand; CHECK (IntItem);
while (Restart) {
if (!OpenDisplay()) {
UNCHECK(HiresItem); UNCHECK(InterItem);
if (! OpenDisplay()) CloseStuff();
Message("Not enough memory for screen ",NULL,"Proceed");
}
StopCalc = Stopped = Restart = FALSE;
dx = (xmax-xmin) / DotsH; dy = (ymax-ymin) / DotsV;
NoZoom = ISCHECKED(ThreeDItem) != NULL;
SubDivide (0L,0L,(LONG)(DotsH-1),(LONG)(DotsV-1));
UNCHECK(TurboItem); SetDepth();
while (!Stopped && !Restart) {
WaitPort(ManWin->UserPort);
TestInput();
}
}
CloseStuff();
}
/* General routines */
CloseStuff()
{
DisableCycle();
if (ManWin) {
ClearMenuStrip (ManWin);
CloseWindow (ManWin);
}
if (ManScr) CloseScreen (ManScr);
if (MathTransBase) CloseLibrary ((struct Library *)MathTransBase);
if (MathBase) CloseLibrary ((struct Library *)MathBase);
CloseLibrary ((struct Library *)GfxBase);
CloseLibrary ((struct Library *)IntuitionBase);
if (ArpBase) CloseLibrary ((struct Library *)ArpBase);
}
OpenDisplay()
{
CycleTemp = CycleOn; DisableCycle();
if (ManWin != NULL) {
ClearMenuStrip(ManWin);
CloseWindow(ManWin);
ManWin = NULL;
}
if (ManScr != NULL) {
CloseScreen(ManScr);
ManScr = NULL;
}
ScrStruct.ViewModes = (ISCHECKED(InterItem) ? LACE : NULL)
+ (ISCHECKED(HiresItem) ? HIRES : NULL)
+ (ISCHECKED(EHBItem) ? EXTRA_HALFBRITE : NULL);
YRes = WinStruct.Height = ScrStruct.Height = (ISCHECKED(InterItem) ? (ScrH * 2) : ScrH);
XRes = WinStruct.Width = ScrStruct.Width = (ISCHECKED(HiresItem) ? 640 : 320);
Factor = (YRes == (ScrH * 2) ? 1 : 2) * (XRes == 640 ? 2 : 1);
Depth = ScrStruct.Depth =
((ISCHECKED(HiresItem) ? 4:5) + (ISCHECKED(EHBItem) ? 1 : 0));
TurboDepth = (ISCHECKED(HiresItem) ? 2 : 4);
/* screen and window */
if (!(ManScr = OpenScreen(&ScrStruct))) return(FALSE);
WinStruct.Screen = ManScr;
if (!(ManWin = OpenWindow(&WinStruct))) return(FALSE);
Manrp = ManWin->RPort;
Manvp = &(ManScr->ViewPort);
LoadRGB4(Manvp,Palette,(NumCol = ISCHECKED(HiresItem) ? 16L: 32L));
ColorMax = NumCol * (ISCHECKED(EHBItem) ? 2:1);
SetDepth();
UNCHECK(TitleItem); TITLECHECK;
SetMenuStrip (ManWin,&ProjectMenu);
if (CycleTemp) EnableCycle();
if (ISCHECKED(ThreeDItem)) {
XOffset = (DotsH = XRes/2)/2; YOffset = (DotsV = YRes/2)/2;
Dot = Dot3D; Box = Box3D;
CalcMandel = CalcMandel3D;
}
else {
DotsH = XRes; DotsV = YRes;
Dot = Dot2D; Box = Box2D;
CalcMandel = CalcMandel2D;
}
return(TRUE);
}
SetDepth() /* Turbo */
{
struct UCopList *cl;
long dispconreg;
CycleTemp = CycleOn; DisableCycle();
FreeVPortCopLists(Manvp);
dispconreg = (Manvp->Modes & ~EXTRA_HALFBRITE) & 0x8fff;
dispconreg |= (ISCHECKED(TurboItem)? TurboDepth : Depth) << 12;
cl = (struct UCopList *)AllocMem ((LONG)sizeof(struct UCopList)
,MEMF_PUBLIC|MEMF_CLEAR);
CWAIT (cl, 0L, 1L); CMOVE (cl, custom.bplcon0, dispconreg); CEND (cl);
Manvp->UCopIns = cl;
MakeScreen(ManScr); RethinkDisplay();
if (CycleTemp) EnableCycle();
}
CalcNewPar(x1,y1,x2,y2)
LONG x1,y1,x2,y2;
{
LONG res;
if (x2<x1) { res=x1; x1=x2; x2=res; }
if (y2<y1) { res=y1; y1=y2; y2=res; }
xmax = xmin + x2*dx; xmin = xmin + x1*dx;
ymin = ymax - y2*dy; ymax = ymax - y1*dy;
}
Message(Text,Yes,No)
UBYTE *Text,*Yes,*No;
{
ULONG width;
width = 40L + TextLength (Manrp,Text,(LONG)strlen(Text));
BodyText.IText = Text; BodyText.LeftEdge = 10L;
YesText.IText = Yes; NoText.IText = No;
return (AutoRequest(ManWin,&BodyText,Yes ? &YesText:NULL,&NoText,
NULL,NULL,width,50L));
}
CompBox(x,y,Distx,Disty)
LONG x,y,Distx,Disty;
{
SetDrMd (Manrp,COMPLEMENT);
BoxOn = !BoxOn;
Move(Manrp,x-Distx,y-Disty);
Draw(Manrp,x+Distx,y-Disty); Draw(Manrp,x+Distx,y+Disty);
Draw(Manrp,x-Distx,y+Disty); Draw(Manrp,x-Distx,y-Disty);
SetDrMd (Manrp,JAM1);
}
/* Change coordinates */
SetCoords ()
{
SHORT Exit = FALSE,RCode = FALSE;
UWORD id;
float res;
struct IntuiMessage *msg,im;
struct Gadget *ActG;
newcoowin.LeftEdge = (XRes-200)/2; newcoowin.TopEdge = (YRes-100)/2;
newcoowin.Screen = ManScr;
if (!(CoordWin = OpenWindow (&newcoowin))) {
Message ("Can't open window !",NULL,"Proceed");
return (FALSE);
}
Coordrp = CoordWin->RPort;
PrintIText(Coordrp,&TLText,0L,0L);
sprintf (topleftx, "%f", xmin); sprintf (toplefty, "%f", ymax);
sprintf (bottomrightx, "%f", xmax); sprintf (bottomrighty, "%f", ymin);
RefreshGList (&TLxG, CoordWin, NULL, 4L);
ActivateGadget (&TLxG, CoordWin, NULL);
ActG = &TLxG;
while (!Exit) {
WaitPort (CoordWin->UserPort);
msg = (struct IntuiMessage *)GetMsg(CoordWin->UserPort);
im = *msg;
ReplyMsg (msg);
id = ((struct Gadget *)im.IAddress)->GadgetID;
switch (im.Class) {
case GADGETUP:
switch (id) {
case OK:
sscanf (topleftx, "%f", &xmin);
sscanf (toplefty, "%f", &ymax);
sscanf (bottomrightx, "%f", &xmax);
sscanf (bottomrighty, "%f", &ymin);
Exit = RCode = TRUE;
break;
case CANCEL:
Exit = TRUE;
RCode = FALSE;
break;
default:
ActG = (ActG == &BRyG ? &TLxG : ActG->NextGadget);
ActivateGadget (ActG, CoordWin, NULL);
break;
}
}
}
if (xmax < xmin) { res=xmax; xmax=xmin; xmin=res; }
if (ymax < ymin) { res=ymax; ymax=ymin; ymin=res; }
CloseWindow (CoordWin);
return ((int)RCode);
}
/* Palette */
SetPalette()
{
struct IntuiMessage *msg, im;
UBYTE exit = FALSE,TurboOn;
int i, id, oldpos[3], oldstep[3], oldint[3];
ULONG colw, lcol;
static int color = R;
CycleTemp = CycleOn; DisableCycle();
PaletteOn = TRUE;
TurboOn = ISCHECKED(TurboItem);
UNCHECK(TurboItem); SetDepth();
NewPalWin.LeftEdge = (XRes - 292) / 2;
NewPalWin.TopEdge = (YRes - 85) / 2;
NewPalWin.Screen = ManScr;
if (!(PalWin = OpenWindow(&NewPalWin))) {
Message ("Can't open window !",NULL,"Proceed");
return;
}
Palrp = PalWin->RPort;
PrintIText (Palrp,&IText,0L,0L);
colw = (NumCol == 16) ? 23 : 10; lcol = (NumCol == 16) ? 8 : 6;
for (i = 0; i < NumCol - 4; i++ ) {
SetAPen (Palrp,(LONG)i + 4L);
RectFill (Palrp, lcol + i * colw, 15L, lcol - 1 + (i + 1) * colw, 47L);
}
SelectRGB (color);
for (i = 0; i < 3; i++) {
oldint[i] = colint[i]; oldstep[i] = decrstep[i]; oldpos[i] = toppos[i];
}
while (!exit) {
WaitPort (PalWin->UserPort);
msg = (struct IntuiMessage *)(GetMsg (PalWin->UserPort));
im = *msg;
ReplyMsg (msg);
switch (im.Class) {
case RAWKEY: HandleRawkey (&im); break;
case GADGETUP:
id = ((struct Gadget *)im.IAddress)->GadgetID;
switch (id) {
case CANCEL:
for (i = 0; i < 3; i++) {
colint[i] = oldint[i];
decrstep[i] = oldstep[i];
toppos[i] = oldpos[i];
}
PalSinus (R); PalSinus (G); PalSinus (B);
case OK:
exit = TRUE;
break;
case RED:
color = R; SelectRGB (color);
break;
case GREEN:
color = G; SelectRGB (color);
break;
case BLUE:
color = B; SelectRGB (color);
break;
case TOPLEFT:
toppos[color] = (--toppos[color] < 4) ? 31 : toppos[color];
break;
case TOPRIGHT:
toppos[color] = (++toppos[color] > 31) ? 4 : toppos[color];
break;
case SLOPEMIN:
if (--decrstep[color] < 15) {
decrstep[color] = 15; DisplayBeep (ManScr);
}
break;
case SLOPEPLUS:
if (++decrstep[color] > 40) {
decrstep[color] = 40; DisplayBeep (ManScr);
}
break;
case INTPLUS:
if (++colint[color] > 0xf) {
colint[color] = 0xf; DisplayBeep (ManScr);
}
break;
case INTMIN:
if (--colint[color] < 0) {
colint[color] = 0; DisplayBeep (ManScr);
}
break;
}
PalSinus (color);
LoadRGB4 (&ManScr->ViewPort, &Palette[0], 32L);
break;
}
}
if (TurboOn) { CHECK(TurboItem); SetDepth(); }
PaletteOn = FALSE;
if (CycleTemp) EnableCycle();
CloseWindow (PalWin);
}
UWORD colmask[3] = { 0x0ff, 0x0f0f, 0xff0 };
PalSinus (color)
int color;
{
double x, xstep;
int pos1, pos2, i;
UWORD col, mask;
x = 0; xstep = PI2 / decrstep[color];
pos1 = pos2 = toppos[color];
for (i = 0; i < 16; i++) {
col = cos (x) * colint[color];
mask = colmask[color];
if (color == R) col <<= 8; else if (color == G) col <<= 4;
Palette[pos1] = (Palette[pos1] & mask) | col;
Palette[pos2] = (Palette[pos2] & mask) | col;
x += xstep;
pos1 = (++pos1 > 31) ? 4 : pos1; pos2 = (--pos2 < 4) ? 31 : pos2;
}
}
SelectRGB (color)
int color;
{
RedG.Flags &= ~SELECTED; BlueG.Flags &= ~SELECTED; GreenG.Flags &= ~SELECTED;
switch (color) {
case R: RedG.Flags |= SELECTED;break;
case G: GreenG.Flags |= SELECTED;break;
case B: BlueG.Flags |= SELECTED;break;
}
SetAPen (Palrp, 0L);
RectFill (Palrp, 174L, 52L, 286L, 66L);
RefreshGList (&RedG, PalWin, NULL, 3L);
}
/* intuition event handling */
#define TAB 0x42
#define UP 0x4c
#define DOWN 0x4d
#define LEFT 0x4f
#define RIGHT 0x4e
HandleRawkey (msg)
struct IntuiMessage *msg;
{
switch (msg->Code) {
case TAB:
if (!PaletteOn) {
if (msg->Qualifier & (IEQUALIFIER_LSHIFT+IEQUALIFIER_RSHIFT))
CycleLeft = !CycleLeft;
else if (CycleOn) DisableCycle();
else EnableCycle();
}
break;
case UP:
if (CycleOn) if (CycleSpeed > 1) CurrSpeed = --CycleSpeed;
else DisplayBeep (ManScr);
break;
case DOWN:
if (CycleOn) CurrSpeed = ++CycleSpeed;
break;
case LEFT:
if (!CycleOn) {
PaletteLeft();
LoadRGB4 (Manvp, Palette, 32L);
}
break;
case RIGHT:
if (!CycleOn) {
PaletteRight();
LoadRGB4 (Manvp, Palette, 32L);
}
break;
}
}
TestInput()
{
struct IntuiMessage *msg,im;
short DoLoop= TRUE, Zooming = FALSE;
LONG XCoord,YCoord,Distx,Disty;
while (DoLoop){
if (msg=(struct IntuiMessage *)(GetMsg(ManWin->UserPort))) {
im = *msg;
ReplyMsg(msg);
switch (im.Class) {
case RAWKEY: HandleRawkey (&im); break;
case MENUPICK: switch (MENUNUM(im.Code)) {
case PROJECT:
switch (ITEMNUM(im.Code)) {
case LOAD: GetIff(); break;
case SAVE: SaveIff(); break;
case TITLE: TITLECHECK; break;
case ABOUT:
Message ("Programmed by Ph.Marivoet, N.Francois", NULL, "Proceed");
break;
case QUIT:
if (Message("Do you want to quit","Yes","No"))
Stopped = StopCalc = TRUE;
break;
}
break;
case MANDEL:
switch (ITEMNUM(im.Code)) {
case COORD:
if (SetCoords()) Restart = StopCalc = TRUE;
break;
case RESET:
if (Message("Reset Mandel","Yes","No")) {
xmax = 1.25; xmin = -2.25;
ymax = 1.5; ymin = -1.5;
StopCalc = Restart = TRUE;
}
break;
case RESTART:
if (Message("Restart Calculation","Yes","No"))
StopCalc = Restart = TRUE;
break;
case ACCURACY:
CalcAllPoints=((DivDegree=SUBNUM(im.Code))==SUPER);
DivNumber = 1<<DivDegree;
break;
case DEPTH:
if (SUBNUM(im.Code)==CUSTOMD) {
if (GetName("Iteration",ItBuffer,FALSE))
sscanf(ItBuffer,"%ld",&MaxIter);
}
else MaxIter = 1 << (SUBNUM(im.Code)+5);
break;
case CALCULATION:
if (ISCHECKED(FloatItem)) Mand = FloatMand;
else Mand = Int32Mand;
break;
}
break;
case SCREEN:
switch(ITEMNUM(im.Code)) {
case NEWSCR:
if (Message("New Screen","Yes","No"))
StopCalc=Restart=TRUE;
break;
case TURBO: SetDepth(); break;
case PALETTE: SetPalette(); break;
}
break;
}
break;
case MOUSEBUTTONS:
if (!NoZoom)
switch (im.Code) {
case SELECTDOWN:
Zooming = TRUE;
XCoord = im.MouseX;
YCoord = im.MouseY;
Distx = Disty = 0;
ReportMouse (ManWin , TRUE);
break;
case SELECTUP:
Zooming = FALSE;
ReportMouse (ManWin , TRUE);
if (Distx != 0 && Disty != 0)
if (Message("Zoom area in ?","Yes","No")) {
CalcNewPar(XCoord-Distx,YCoord-Disty,
XCoord+Distx,YCoord+Disty);
StopCalc = Restart = TRUE;
}
if (BoxOn) CompBox(XCoord,YCoord,Distx,Disty);
break;
}
break;
case MOUSEMOVE:
if (Zooming) {
if (BoxOn) CompBox(XCoord,YCoord,Distx,Disty);
Distx = XCoord-im.MouseX;
Disty = YCoord-im.MouseY;
CompBox(XCoord,YCoord,Distx,Disty);
}
break;
}
}
DoLoop = Zooming;
}
}
/* Function for ARP filerequester (requester on our screen) */
void AdjustArpReq (ULONG Mask, struct NewWindow *win)
{
win->Screen = ManScr;
win->Type = CUSTOMSCREEN;
win->LeftEdge = (XRes-win->Width)/2;
win->TopEdge = (YRes-win->Height)/2;
}
UBYTE *GetName (title, str, FileReq)
UBYTE *title, *str;
BOOL FileReq;
{
static UBYTE Path[108];
UBYTE File[256];
if (req && FileReq) {
req->fr_Hail = title;
req->fr_Dir = Path;
strcpy (str,FileRequest (req));
if (*str) {
strcpy (File,Path);
TackOn (File,str);
strcpy (str,File);
return (str);
}
else return (NULL);
}
StringGInfo.Buffer = str;
NewStringWin.LeftEdge = (XRes-200)/2; NewStringWin.TopEdge = (YRes-40)/2;
NewStringWin.Screen = ManScr;
NewStringWin.Title = title;
if (!(StringWin = OpenWindow (&NewStringWin))) {
Message ("Can't open window !",NULL,"Proceed");
return (NULL);
}
ActivateGadget (&StringG, StringWin, NULL);
WaitPort (StringWin->UserPort);
CloseWindow (StringWin);
if (*str) return (str);
else return (NULL);
}
/* IFF load/save */
GetIff()
{
LONG d, i;
struct IntuiMessage *msg;
if (!GetName("Load file", fname, TRUE)) return;
MandChunk.XSide[0] = NULL;
if (read_iff (&myILBMinfo,fname,1)) {
if (!MandChunk.XSide[0])
if (!Message ("MANDEL chunk not found, load anyway ?","Yes","No"))
return;
if ((myILBMinfo.header.h > (ScrH * 2)) || (myILBMinfo.header.w > 640)) {
Message ("Picture too large, can't load",NULL,"Ok");
return;
}
if ((myILBMinfo.header.w > 320) && (myILBMinfo.header.nPlanes > 5)) {
Message ("Picture too large, can't load",NULL,"Ok");
return;
}
NoZoom = StopCalc = TRUE;
UNCHECK(TurboItem);
if ((d = myILBMinfo.header.nPlanes) > 5) { d = 5; CHECK(EHBItem); }
for (i = 0; i < 1<<d; i++)
Palette[i] = ((myILBMinfo.cmap[3 * i] & 0xf0) << 4)
+ (myILBMinfo.cmap[3 * i + 1] & 0xf0)
+((myILBMinfo.cmap[3 * i + 2] & 0xf0) >> 4);
if (myILBMinfo.header.h > ScrH) CHECK (InterItem);
else UNCHECK (InterItem);
if (myILBMinfo.header.w > 320) CHECK (HiresItem);
else UNCHECK (HiresItem);
if (!OpenDisplay()) {
UNCHECK (HiresItem); UNCHECK (InterItem);
if (!OpenDisplay()) Stopped = TRUE;
else Message ("No memory for screen !",NULL,"Proceed");
}
else {
ModifyIDCMP (ManWin, MENUVERIFY);
if (MandChunk.XSide[0]) {
xmax = (xmin = I2F(MandChunk.XCoo)) + I2F(MandChunk.XSide);
ymax = (ymin = I2F(MandChunk.YCoo)) + I2F(MandChunk.YSide);
dx = (xmax-xmin) / DotsH;
dy = (ymax-ymin) / DotsV;
UNCHECK (D32Item); UNCHECK (D64Item); UNCHECK (D128Item);
UNCHECK (D256Item); UNCHECK (D512Item); UNCHECK (D1024Item);
UNCHECK (DCustItem);
switch (MaxIter = MandChunk.Iteration) {
case 32: CHECK (D32Item); break;
case 64: CHECK (D64Item); break;
case 128: CHECK (D128Item); break;
case 256: CHECK (D256Item); break;
case 512: CHECK (D512Item); break;
case 1024: CHECK (D1024Item); break;
default:
CHECK (DCustItem);
sprintf (ItBuffer, "%ld", MaxIter);
break;
}
UNCHECK (FloatItem); UNCHECK (IntItem);
if (MandChunk.Calculation == CALC_INT32) {
CHECK (IntItem); Mand = Int32Mand;
}
else {
CHECK (FloatItem); Mand = FloatMand;
}
if (MandChunk.Flags & MAND_3D)
CHECK (ThreeDItem);
else {
UNCHECK (ThreeDItem); NoZoom = FALSE;
}
for (i = 0; i < 3; i++) {
toppos[i] = MandChunk.TopPos[i];
decrstep[i] = MandChunk.DecrStep[i];
colint[i] = MandChunk.ColInt[i];
}
}
myILBMinfo.bitmap = ManScr->BitMap;
myILBMinfo.bitmap.BytesPerRow = ((myILBMinfo.header.w+15)>>4)<<1;
myILBMinfo.bitmap.Rows = myILBMinfo.header.h;
myILBMinfo.bitmap.Depth = myILBMinfo.header.nPlanes;
if (!read_iff (&myILBMinfo,fname, 0))
Message ("Error loading file !",NULL,"Proceed");
}
}
else Message ("Can't load IFF file !",NULL,"Proceed");
while (msg = (struct IntuiMessage *)GetMsg (ManWin->UserPort))
ReplyMsg (msg);
ModifyIDCMP (ManWin, RAWKEY+MOUSEMOVE+MENUPICK+MOUSEBUTTONS);
}
SaveIff()
{
struct IntuiMessage *msg;
if (!GetName("Save file", fname, TRUE)) return;
ModifyIDCMP (ManWin, MENUVERIFY);
UNCHECK (TitleItem); TITLECHECK;
F2I(MandChunk.XCoo, xmin); F2I(MandChunk.XSide, xmax - xmin);
F2I(MandChunk.YCoo, ymin); F2I(MandChunk.YSide, ymax - ymin);
MandChunk.Iteration = MaxIter;
if (ISCHECKED(IntItem)) MandChunk.Calculation = CALC_INT32;
else MandChunk.Calculation = CALC_FFP;
MandChunk.Flags = 0;
if (CalcMandel == CalcMandel3D) MandChunk.Flags |= MAND_3D;
for (i = 0; i < 3; i++) {
MandChunk.TopPos[i] = toppos[i];
MandChunk.DecrStep[i] = decrstep[i];
MandChunk.ColInt[i] = colint[i];
}
if (!write_iff (fname,&Palette[0], ManScr, 1))
Message ("Couldn't save IFF file !",NULL,"Proceed");
while (msg = (struct IntuiMessage *)GetMsg (ManWin->UserPort))
ReplyMsg (msg);
ModifyIDCMP (ManWin, RAWKEY+MOUSEMOVE+MENUPICK+MOUSEBUTTONS);
DisplayBeep (ManScr);
}
/* 2D-3D subroutines */
LONG CalcMandel2D(ix,iy)
LONG ix,iy;
{
LONG color;
float x,y;
if (!(color = ReadPixel(Manrp,ix,iy))) {
x = xmin+ix*dx;
y = ymax-iy*dy;
color = Mand(x,y,MaxIter);
SetAPen(Manrp,color);
WritePixel(Manrp,ix,iy);
}
return(color);
}
LONG CalcMandel3D(ix,iy)
LONG ix,iy;
{
return (Mand ((float)xmin+ix*dx, (float)ymax-iy*dy, MaxIter));
}
void Dot2D(x,y,col)
LONG x,y,col;
{
SetAPen(Manrp,col); WritePixel(Manrp,x,y);
}
void Dot3D(x,y,col)
LONG x,y,col;
{
SetAPen (Manrp, col == 2L ? 2L : (col == 4L ? 31L : col-1L));
Move (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset-col);
Draw (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset);
SetAPen (Manrp,col);
WritePixel (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset-col);
}
void Box2D(x1,y1,x2,y2,col)
LONG x1,y1,x2,y2,col;
{
SetAPen(Manrp,col); RectFill(Manrp,x1,y1,x2,y2);
}
void Box3D(x1,y1,x2,y2,col)
LONG x1,y1,x2,y2,col;
{
LONG i, bcol;
bcol = (col == 2L ? 2L : (col == 4L ? 31L : col-1L));
SetAPen (Manrp, bcol);
RectFill (Manrp, x1+XOffset+(YOffset-y2)*Factor/2, y2+YOffset-col,
x2+XOffset+(YOffset-y2)*Factor/2, y2+YOffset);
for (i=y1; i<=y2; i++) {
SetAPen (Manrp, bcol);
Move (Manrp, x2+XOffset+(YOffset-i)*Factor/2, i+YOffset);
Draw (Manrp, x2+XOffset+(YOffset-i)*Factor/2, i+YOffset-col);
SetAPen(Manrp,col);
Draw (Manrp, x1+XOffset+(YOffset-i)*Factor/2, i+YOffset-col);
}
}
/* Recursive calculation of mandelbrot */
SubDivide(x1,y1,x2,y2)
LONG x1,x2,y1,y2;
{
static LONG i,TestColor;
LONG mx1,my1,mx2,my2,SameColor = TRUE,Step;
if (StopCalc) return;
if ((x1==x2) && (y1==y2)) {
Dot(x1,y1,CalcMandel(x1,y1)); return;
}
mx1 = mx2 = (x1+x2)/2;
my1 = my2 = (y1+y2)/2;
TestColor = CalcMandel (mx1,my1);
if (CalcAllPoints || !(Step=(x2-x1)/DivNumber)) Step = 1;
for (i = 0; (i <= x2-x1) && !StopCalc; i += Step) {
SameColor &= TestColor == CalcMandel (x1+i,y1);
SameColor &= TestColor == CalcMandel (x2-i,y2);
TestInput();
}
if (CalcAllPoints || !(Step=(y2-y1)/DivNumber)) Step = 1;
for (i = 0 ;(i <= y2-y1) && !StopCalc; i += Step) {
SameColor &= TestColor == CalcMandel (x1,y2-i);
SameColor &= TestColor == CalcMandel (x2,y1+i);
TestInput();
}
if (SameColor && !StopCalc) Box(x1,y1,x2,y2,TestColor);
else {
if ((x2-x1) == 1) mx2 = mx1 +1; if ((y2-y1) == 1) my2 = my1 +1;
SubDivide (x1 ,y1 ,mx1,my1); SubDivide (x1 ,my2,mx1,y2 );
SubDivide (mx2,y1 ,x2 ,my1); SubDivide (mx2,my2,x2 ,y2 );
}
}
float fixedfactor = (float)(1L << 27);
LONG Int32Mand (px, py, max_iter)
float px, py;
LONG max_iter;
{
register LONG color = 2;
LONG itcountint;
itcountint = Int32Mand_asm((long)(px * fixedfactor),(long)(py * fixedfactor),max_iter);
if (itcountint) color = (max_iter - itcountint) % (ColorMax-4) + 4;
return (color);
}
LONG FloatMand (px,py,max_iter)
float px,py;
LONG max_iter;
{
LONG color = 2,itcount;
itcount = FloatMand_asm(px,py,max_iter);
if (itcount) color = (max_iter - itcount) % (ColorMax-4) + 4;
return(color);
}
/* Cycle subtask */
void __saveds DoCycle()
{
DoCycle_asm();
}
EnableCycle()
{
struct Task *CycleTask;
if (!CycleOn)
CycleTask = (struct Task *)CreateTask ("TM VBlank", 2L, DoCycle, 1000L);
CycleOn = TRUE;
}
DisableCycle()
{
CycleOn = FALSE; WaitTOF(); WaitTOF();
}